Error Handling
exception handling
例外が起きた時に、それをどう処理するか
プログラムを落とさずに、決められた次の処理を行いたい
catchにかかれているような処理を例外ハンドラという
例外の例
用語
この記事に則って用語を整理する
table:用語
用語 意味
失敗 命名された処理が期待される処理を完了できなかった
バグ 必ず起きる失敗
例外 たまに起きる失敗
例外処理 例外的な状況に対応する行為や機構
例外機構 例外処理のための言語が用意している機構
エラーハンドリングの目的
例外が生じた際にプログラムがクラッシュすることは避けたい
続行不能にするのではなく、どうにかして継続させたい
できれば例外が起きる前の状態へrollbackしたい
せめてデータは整合性の取れる状態にしたい
生じた例外の原因の特定に寄与する
#WIP
この記事で回復可能性と合わせての分類があった
上に行くほど回復可能
デフォルト値
エラー値ではなく[]などのデフォルト値を返す
Simple Domain Error
e.g. null, nil, Maybe, Optional
エラーであることのみを返す
直和
e.g. Either, Result, 多値リターン
エラーと正常系を両方返す
検査例外
非検査例外
catch不能エラー
e.g. SwiftのfatalError()
そのエラーの責任が呼び出し元にある場合は、回復可能なエラーで返す
その処理の内部に問題がある場合は、回復不可能なエラーを返す
呼び出し元はその公開されているinterfaceからはどうしようもないので
関数というより、RESTFul APIとかformのようなものほうがイメージしやすい
何かエラーがあったときに、入力を変えて再度呼び出せば改善されるのかどうか
しかし、これ、回復可能性でエラーの方法を変えるの、どれぐらい妥当なのだろうかmrsekut.icon
例えば、回復不可能なエラーに対し、Eitther型を使うことにどういう問題があるのか
また、上記の分類も既存のerror値を分類しただけに過ぎない
例えば、effect typeのような他の新たな機構を前提すると、そもそも上記のような分類が不要になるということはないだろうか
https://zenn.dev/murnana/articles/swift-error-handling-rationale
swiftがそういうエラー分類をしているらしい
Simple domain errors (単純なドメインエラー)
Recoverable errors (回復可能なエラー)
Universal errors (普遍的なエラー)
Logic failures (論理的な失敗)
例外機構を用いたError Handling
手続き的プログラミングでよく見るmrsekut.icon
例外を順々に関数の呼び出し元に例外を伝搬させていき、処理できる箇所で処理する
catchのような例外機構を用いる
どこかで例外が起きた場合は処理が中断され、
その関数の呼び出し元、それの呼び出し元、、と巻き戻っていく
try節の中まで戻ってきたら、catch節の処理へ移行する
catchの中で回復しきれないときは、さらに例外を投げることもある
code:ts
try { .. } catch (e: Error) { throw e; }
関数を見た時に、それが例外を発しうるかどうかを見た目で判断できない
型を用いたError Handlingをする
関数型プログラミングでよく見るmrsekut.icon
Errorを表す型を用いて、Errorを値として扱う
具体的にはMaybeやEitherなど
関数の型に現れるので、型を見ればそれが失敗しうるのかどうか判別できる
値用いたError Handling
Go言語とか
関数が(value, error)の2値を返し、呼び出し側がhandlingする
React ComponentレベルのError Handling
Error Boundary
構造としては、例外機構を用いたものに近い
子Componentがthrowしたものを、親Componentがhandlingして、「エラーが発生しました」のようなUIを表示する
errorを表すglobal変数を使う
この辺の説明を読んで、
Shell Sciprtのエラーって2だったらなんたらみたいなのよな、と思い出した
C言語もShellScriptも詳しくないので、これが似たものなのかそうではないのかの判断ができないmrsekut.icon
C言語には例外処理がない(?)
JavaScript
https://qiita.com/uhyo/items/2c2c90ecf1ceb966c88a
現状stage2の機能について
https://jsprimer.net/basic/error-try-catch/
Julia
https://scls.gitbooks.io/ljthw/content/_chapters/11-ex8.html
Elixir
https://www.slideshare.net/piacere_ex/elixir6elixirtrycatch
https://qiita.com/tbpgr/items/088e134b2d83c7a4eea7
https://qiita.com/melpon/items/2d263f3b91d48168f038
https://elixirschool.com/ja/lessons/advanced/error-handling/
Icon言語言語のエラー処理機構
ゴール指向評価の機能によって、例外処理用の文法を言語に導入しなくても、つまり、例外処理のための記述を意識せずにふつうにプログラムを書いてるだけで例外処理が入っているということになる
デメリットは例外処理が目立たなくなってしまうこと
つまり、普通の言語と見た目が変わってしまうMatz.icon
普通にこれ良いのでは?mrsekut.icon
https://go.googlesource.com/proposal/+/master/design/go2draft-error-handling-overview.md
Goのcheck/handleについてのdraft
エラー処理のせいで、本筋の処理が埋もれる問題の対処
https://gakuzzzz.github.io/slides/error_handling_practice/
よくまとまっている
Nim
https://nim-lang.org/docs/tut2.html#exceptions
エラーが起きたときに、どのようなメッセージを出力するか
エラー出力
参考
『言語のしくみ』
エラーハンドリング
例外入門以前 - Qiita
2014年の例外アドベントカレンダーの目次的なもの
実際は頓挫されたようで詳細の記事は4つしかないが、目次として勉強の道標になる
例外安全と例外中立 - Qiita
https://ja.wikipedia.org/wiki/例外処理
他人のコードや設計を見て1番これはあり得ないだろと思う実装はありますか?に対するKengo Nakajimaさんの回答 - Quora
超堅牢なやつ
『コーディングを支える技術』の6章とか
https://qiita.com/Kokudori/items/3a953c00012408f76ab9#%E4%BE%8B%E5%A4%96%E7%9A%84%E7%8A%B6%E6%B3%81
https://www.slideshare.net/t_wada/exception-design-by-contract
https://qiita.com/draftcode/items/d9c1aa0ef63b100923dd
https://qiita.com/yuya_presto/items/3b651d6b0cf38f77e933
https://qiita.com/Kokudori/items/987073d59529b6c9a37c
https://qiita.com/Kokudori/items/2e4bd32abf7abea3186f
https://qiita.com/Kokudori/items/30ef407e9ee135cb73f6
https://qiita.com/Kokudori/items/0fe9181d8eec8d933c98
https://qiita.com/Kokudori/items/3a953c00012408f76ab9#%E4%BE%8B%E5%A4%96-advent-calendar-2014%E3%81%AE%E7%B6%99%E7%B6%9A%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6
https://doc.rust-jp.rs/the-rust-programming-language-ja/1.6/book/error-handling.html#%E5%9F%BA%E7%A4%8E
https://gakuzzzz.github.io/slides/error_handling_practice/#1